package com.restphp.java.hashdb.dcs;

import com.restphp.java.hashdb.core.HashDbCore;
import com.restphp.java.hashdb.dcs.client.HashDbClusterClient;
import com.restphp.java.hashdb.dcs.po.ClusterNode;
import com.restphp.java.hashdb.dcs.utils.ClusterNodeUtils;

import java.util.List;
import java.util.Random;

/**
 * 从群集中获取key值.
 * Created by sofical on 2020/8/11.
 */
public class GetFromCluster {
    private HashDbClusterConfig clusterConfig = null;
    public GetFromCluster(HashDbClusterConfig clusterConfig) {
        this.clusterConfig = clusterConfig;
    }

    public <T> T get (String root, String table, String key, Class<T> tClass) {
        //为空表示非群集模式
        if (null == clusterConfig) {
            return HashDbCore.get(root, table, key, tClass);
        }

        // 群集里是否有本地.
        for (ClusterNode node : this.clusterConfig.nodeList()) {
            String ip = ClusterNodeUtils.getHostAddress(node);
            Boolean isLocal = ClusterNodeUtils.isLocal(ip, node.getIpType());

            if (isLocal) {
                return HashDbCore.get(root, table, key, tClass);
            }
        }

        // 从群集节点中获取
        return requestCluster(root, table, key, tClass);
    }

    /**
     * 从群集里
     * @param root
     * @param table
     * @param key
     * @param <T>
     * @return
     */
    private <T> T requestCluster (String root, String table, String key, Class<T> tClass) {
        ClusterNode node = getNode(this.clusterConfig.nodeList());
        HashDbClusterClient clusterClient = new HashDbClusterClient();
        return clusterClient.get(node, root, table, key, tClass);
    }

    /**
     * 随机获取一个节点.
     * @param nodes cluster node list
     * @return cluster node.
     */
    private ClusterNode getNode (List<ClusterNode> nodes) {
        Integer max = nodes.size() - 1;
        Integer min = 0;
        Random random = new Random();
        Integer index = random.nextInt(max) % (max - min + 1) + min;
        return nodes.get(index);
    }
}
